﻿using System;
using System.Collections;
using System.Collections.Generic;
using AutoPoco;
using AutoPoco.Engine;

namespace Autopoco.Contrib
{
    public class Generator : IGenerator
    {
        private readonly IDictionary<Type, IDataGenerator> _dataGenerators = new Dictionary<Type, IDataGenerator>();
        private readonly IDictionary<Type, Queue> _queues = new Dictionary<Type, Queue>();
        private readonly IGenerationSessionFactory _factory;
        private readonly IGenerationSession _session;
        private static readonly object syncObj = new object();

        public Generator(params IDataGenerator[] dataGenerators)
        {
            _factory = AutoPocoContainer.Configure(x =>
                                                          {

                                                              foreach (var dataGenerator in dataGenerators)
                                                              {
                                                                  if (_dataGenerators.ContainsKey(dataGenerator.Type))
                                                                      continue;
                                                                  _dataGenerators.Add(dataGenerator.Type,
                                                                                      dataGenerator);
                                                                  dataGenerator.Configure(x);
                                                              }
                                                          });
            _session = _factory.CreateSession();
        }
        public T Next<T>() where T : class
        {
            lock (syncObj)
            {
                if (!_queues.ContainsKey(typeof(T)) || _queues[typeof(T)].Count < 1)
                {
                    var list = _session.List<T>(100000).Get();
                    var array = new T[list.Count];
                    list.CopyTo(array, 0);
                    _queues[typeof(T)] = new Queue(array);
                }
                return _queues[typeof(T)].Dequeue() as T;
            }
        }
    }
}